﻿/**********************************************************************
 * @file   RunWidget.h
 * @brief  求解器运行界面
 * @author BaGuijun (baguijun@163.com)
 * @date   2024-09-02
 *********************************************************************/
#ifndef _RunWidget_H
#define _RunWidget_H

#include "GUICalculateDialogAPI.h"
#include "GUICalculateWidgetBase.h"
#include <QFile>
#include <QList>
//#include <vtkCell.h>
//#include <vtkCellType.h>
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaMaterialBehavior.h"

class QAbstractButton;
class QDomDocument;
class QTextStream;
class QDataStream;
class QDomElement;

namespace Ui {
    class RunWidget;
}

namespace EventOper {
    class ParaWidgetInterfaceOperator;
}

namespace Interface {
    class FITKOFRunControl;
    class FITKUnstructuredMeshVTK;
    class FITKAbstractMaterial;
    class FITKAbaMaterial;
    class FITKAbaMaterialBehavior;
    class FITKSimulationParameters;
}

namespace Core
{
    class FITKAbstractNDataObject;
    class FITKParameter;
    class FITKParamBool;
    class FITKParamInt;
    class FITKParamDouble;
    class FITKParamString;
    class FITKParamBoolGroup;
    class FITKParamCombox;
    class FITKParamDoubleList;
    class FITKParamRadioGroup;
    class FITKParamLabel;
}

namespace GUI
{
    /**
     * @brief  求解器CPU状态
     * @author BaGuijun (baguijun@163.com)
     * @date   2024-09-02
     */
    enum class RunCPUType {
        Serial,
        Parallel,
    };
    class MeshKernal;
    class MeshSet;
    class MeshData;

    /**
     * @brief  求解器运行界面
     * @author BaGuijun (baguijun@163.com)
     * @date   2024-09-02
     */
    class GUICalculateDialogAPI RunWidget : public GUICalculateWidgetBase
    {
        Q_OBJECT;
    public:
        /**
         * @brief    构造函数
         * @param[i] oper      操作器对象
         * @param[i] parent    父对象
         * @author   BaGuijun (baguijun@163.com)
         * @date     2024-09-02
         */
        RunWidget(EventOper::ParaWidgetInterfaceOperator* oper, QWidget* parent = nullptr);
        /**
         * @brief    析构函数
         * @author   BaGuijun (baguijun@163.com)
         * @date     2024-09-02
         */
        ~RunWidget();
        /**
         * @brief    初始化
         * @author   BaGuijun (baguijun@163.com)
         * @date     2024-09-02
         */
        void init();
        /**
         * @brief    显示事件
         * @param[i] event   事件对象
         * @author   BaGuijun (baguijun@163.com)
         * @date     2024-09-02
         */
        void showEvent(QShowEvent * event);
        /**
         * @brief    隐藏事件
         * @param[i] event   事件对象
         * @author   BaGuijun (baguijun@163.com)
         * @date     2024-09-02
         */
        void resizeEvent(QResizeEvent * event);
        //写xml文件所需函数定义
        //bool write(QString dir = QString());
        void setFileName(const QString &name);
        void write_xml_model();
        void write_xml_material();
        void write_xml_geometry();
        void write_xml_meshdata();
//        QDomElement& writeToProjectFile(QDomDocument* doc, QDomElement* e);
        QDomElement& writeToProjectFileNOMeshSetButWirteToolForceInformation(QDomDocument* doc, QDomElement* parent);
        QDomElement& writeToProjectMaterialFile(QDomDocument* doc, QDomElement* parent);
        QDomElement& writeToProjectModelFile(QDomDocument* doc, QDomElement* parent);
        //写xml
        QDomElement& writeToProjectFileMesh(QDomDocument* doc, QDomElement* ele,Interface::FITKUnstructuredMeshVTK *k);
        QDomElement& writeToProjectFileSet(QDomDocument* doc, QDomElement* ele, Interface::FITKUnstructuredMeshVTK *k);
        QDomElement& writeToProjectFileMaterial(QDomDocument* doc, QDomElement* ele,Interface::FITKAbstractMaterial *k,int &index);
        QDomElement& writeToProjectFileModel(QDomDocument* doc, QDomElement* ele,Interface::FITKSimulationParameters *k);

        void writevalueToMaterialXMLFile(QDomDocument* doc,QDomElement* ele,QString describe,QString value,QString unit,QString Type);
        void writevalueToINTXMLFile(QDomDocument* doc,QDomElement* ele,QString describe,QString value,QString unit,QString Type);
        void writevalueToBOOLXMLFile(QDomDocument* doc,QDomElement* ele,QString describe,QString value,QString unit,QString Type);

        bool parameterBoolW(QDomDocument* doc,QDomElement* parent,Core::FITKParamBool* paraBool);
        bool parameterDoubleW(QDomDocument* doc,QDomElement* parent,Core::FITKParamDouble* paraDouble);
        bool parameterIntW(QDomDocument* doc,QDomElement* parent,Core::FITKParamInt* paraInt);
        bool parameterComboxW(QDomDocument* doc,QDomElement* parent,Core::FITKParamCombox* paraCombox);

        void extractUnitPart(QString input ,QString& TextPart ,QString& UnitPart);

        //QString vtkCellTYpeToString(VTKCellType type);
    private slots:
        ;
        /**
         * @brief    CPU状态修改事件
         * @param[i] button    QRadioButton对象
         * @author   BaGuijun (baguijun@163.com)
         * @date     2024-09-02
         */
        void slotCPUChange(QAbstractButton* button);
        /**
         * @brief    进程结束事件
         * @author   BaGuijun (baguijun@163.com)
         * @date     2024-09-02
         */
        void slotProcessFinish();
        /**
         * @brief    CPU核数修改事件
         * @param[i] arg1 CPU核数
         * @author   BaGuijun (baguijun@163.com)
         * @date     2024-09-02
         */
        void on_spinBox_NumOfPro_valueChanged(int arg1);
        /**
         * @brief    停止按钮点击事件
         * @author   BaGuijun (baguijun@163.com)
         * @date     2024-09-02
         */
        void on_pushButton_Stop_clicked();
        /**
         * @brief    运行按钮点击事件
         * @author   BaGuijun (baguijun@163.com)
         * @date     2024-09-02
         */
        void on_pushButton_Run_clicked();
        void onTypeChanged(const QString& text);
        void onOpenFileButtonClicked();

    private:
        /**
         * @brief    更新时间参数
         * @author   BaGuijun (baguijun@163.com)
         * @date     2024-09-02
         */
        void updataTime();
        /**
         * @brief    更新输出参数
         * @author   BaGuijun (baguijun@163.com)
         * @date     2024-09-02
         */
        void updateOutput();
        /**
         * @brief    初始化CPU
         * @author   BaGuijun (baguijun@163.com)
         * @date     2024-09-02
         */
        void initCPU();
        /**
         * @brief    更新CPU
         * @author   BaGuijun (baguijun@163.com)
         * @date     2024-09-02
         */
        void updateCPU();
        /**
         * @brief    清理算例文件
         * @param[i] casePath  算例路径 
         * @return   bool      是否成功
         * @author   BaGuijun (baguijun@163.com)
         * @date     2024-08-29
         */
        bool clearCasePath(QString casePath);
        /**
         * @brief    写出算例
         * @param[i] casePath  算例路径 
         * @return   bool      是否成功
         * @author   BaGuijun (baguijun@163.com)
         * @date     2024-08-29
         */
        bool writeCase(QString casePath);
        /**
         * @brief    写出xml文件
         * @param[i] casePath  算例路径
         * @return   bool      是否成功
         * @author   liu
         * @date     2025-01-02
         */
        bool writeCase_xml(QString casePath);
        /**
         * @brief    创建启动脚本
         * @param[i] workDir   工作路径
         * @param[i] caseDir   算例路劲
         * @return   QString   脚本路径
         * @author   BaGuijun (baguijun@163.com)
         * @date     2024-08-30
         */
        QString creatStartSh(QString workDir, QString caseDir);
        /**
         * @brief    设置是否是运行状态
         * @param[i] isRun    是否是运行状态
         * @author   BaGuijun (baguijun@163.com)
         * @date     2024-09-02
         */
        void setRunType(bool isRun);
    private:
        /**
         * @brief  UI对象
         * @author BaGuijun (baguijun@163.com)
         * @date   2024-09-02
         */
        Ui::RunWidget* _ui = nullptr;
        /**
         * @brief  求解器运行参数对象
         * @author BaGuijun (baguijun@163.com)
         * @date   2024-09-02
         */
        Interface::FITKOFRunControl* _runConObj = nullptr;


    private:
        bool _visible{ true };
        QString _path{};
        int _pointIDOffset{ 1 };  //起始ID，终止ID=起始ID+mesh.pointnum-1
        int _cellIDOffset{ 1 };

    protected:
        QString       _filename;
        QFile         _file;
        QTextStream  *_stream{};
        QDataStream  *_dataStream{};
        QTextStream  *_textstream{};
        QDomDocument *_doc{};

    };

}

#endif
